﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MulticastTV
{

    /// <summary>
    /// EPG pop-up window
    /// </summary>
    public partial class EPGWindow : Form
    {
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        static extern bool SetWindowPos(
             int hWnd,           // window handle
             int hWndInsertAfter,    // placement-order handle
             int X,          // horizontal position
             int Y,          // vertical position
             int cx,         // width
             int cy,         // height
             uint uFlags);       // window positioning flags

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        private const int HWND_TOPMOST = -1;
        private const uint SWP_NOACTIVATE = 0x0010;
        public const uint WS_POPUP = 0x80000000;
        public const int WS_EX_TOPMOST = 0x8;
        public const int WS_EX_TOOLWINDOW = 0x80;
        public const int WS_EX_LAYERED = 0x80000;
        public const int WS_EX_TRANSPARENT = 0x20;
        public const int WS_EX_NOACTIVATE = 0x08000000;
        public const int SW_SHOWNOACTIVATE = 4;
        public const int SW_HIDE = 0;
        public const uint AW_HOR_POSITIVE = 0x1;
        public const uint AW_HOR_NEGATIVE = 0x2;
        public const uint AW_VER_POSITIVE = 0x4;
        public const uint AW_VER_NEGATIVE = 0x8;
        public const uint AW_CENTER = 0x10;
        public const uint AW_HIDE = 0x10000;
        public const uint AW_ACTIVATE = 0x20000;
        public const uint AW_SLIDE = 0x40000;
        public const uint AW_BLEND = 0x80000;
        
        string itema, itemb, time, diff;
        DateTime ItemTimeA, ItemTimeB;
        float percent = 0;
        Timer clockupdate = new Timer();
        Timer HideFsOsd = new Timer();
        Form1 parent;
        public bool fsodshown = false;
        
        //constructor
        /// <summary>
        /// EPGWindow
        /// </summary>
        /// <param name="Form">Parent form</param>

        public EPGWindow(Form1 pr)
        {
            InitializeComponent();
            CreateHandle();
            parent = pr;
            //this.BackColor = Color.FromArgb(208, 208, 207);

            //if (Properties.Settings.Default.OsdTransparentBackgroundV2 == 1)
            //    this.TransparencyKey = this.BackColor;
            //else
            //    this.TransparencyKey = Color.Empty;
           
            itema = "";
            itemb = "";
            time = DateTime.Now.ToString("HH:mm");
            diff = "";
            clockupdate.Interval = 1000;
            clockupdate.Tick+=new EventHandler(clockupdate_Tick);
            clockupdate.Start();
            HideFsOsd.Interval = Properties.Settings.Default.EPGPopUpTimeOut;
            HideFsOsd.Tick+=new EventHandler(HideFsOsd_Tick);
        }

        /// <summary>
        /// draw info
        /// </summary>
        /// <param name="iA">Item A - current show</param>
        /// <param name="iB">Item B - next show</param>
        /// <param name="dA">Item A - current show time</param>
        /// <param name="dB">Item B - next show time</param>
        public void updateText(string iA, string iB, DateTime dA, DateTime dB)
        {
            HideFsOsd.Stop();
            HideFsOsd.Start();
            fsodshown = true;
            itema = iA;
            itemb = iB;
            ItemTimeA = dA;
            ItemTimeB = dB;
            if (ItemTimeA == DateTime.MinValue)
            {
                itema = "";
                itemb = "";
                diff = "";
                percent = 0;
                this.Invalidate(this.ClientRectangle);
                this.Update();
                return;
            }

            try
            {
                if (itemb != "")
                {
                    double full = ItemTimeB.Subtract(ItemTimeA).TotalMinutes;
                    double elapsed = DateTime.Now.Subtract(ItemTimeA).TotalMinutes; 
                    percent = ((float)elapsed/ (float)full);
                    diff = ItemTimeB.Subtract(DateTime.Now).TotalMinutes.ToString("0' min");
                }
                else
                {
                    diff = "";
                    percent = 0;
                }

                this.Invalidate(this.ClientRectangle);
                this.Update();
                showWindow();
            }
            catch { }
        }

        /// <summary>
        ///Refresh time bar
        /// </summary>
        public void refreshTimeLine()
        {
            if (itemb != "")
            {
                double full = ItemTimeB.Subtract(ItemTimeA).TotalMinutes;
                double elapsed = DateTime.Now.Subtract(ItemTimeA).TotalMinutes;
                percent = Math.Min(((float)elapsed / (float)full),1);

                diff = ItemTimeB.Subtract(DateTime.Now).TotalMinutes.ToString("0' min");
            }
            
            this.Invalidate(this.ClientRectangle);
            this.Update();
        }

        public void clear()
        {
            itema = "";
            itemb = "";
            diff = "";
            percent = 0;
            this.Invalidate(this.ClientRectangle);
            this.Update();
            return; 
        }

        //protected override CreateParams CreateParams
        //{
        //    get
        //    {
        //        CreateParams createParams = base.CreateParams;
        //        if (Properties.Settings.Default.OsdTransparentBackgroundV2 == 1)
        //            createParams.ExStyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT;
                
        //        return createParams;
        //    }
        //}

        private void EPGWindow_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            int test1 = e.ClipRectangle.Width;
            int test2 = this.Width;
            int test3 = e.ClipRectangle.Height;
            int test4 = this.Height;
            int width = e.ClipRectangle.Width;
            int height = e.ClipRectangle.Height;
            Rectangle rect_gray = new Rectangle((int)(width * 0.03f), (int)(height / 2.0f) - 2, width - (int)(width * 0.06f), 4);
            Rectangle rect_green = new Rectangle((int)(width * 0.03), (int)(height / 2.0f) - 2, (int)(percent * (width - (width * 0.06f))), 4);

            if (test1 != 0 && test2 != 0 && test3 != 0 && test4 != 0 && width != 0 && height != 0 && rect_gray.Width!=0 &&  rect_gray.Height != 0)
            {
                //show duration progress bar
                LinearGradientBrush lBrush_gray = new LinearGradientBrush(rect_gray, Color.FromArgb(40, 28, 192, 0), Color.FromArgb(40, 35, 246, 0), LinearGradientMode.Horizontal);
                g.FillRectangle(lBrush_gray, rect_gray);
                if (percent != 0.0f && !float.IsInfinity(percent) && rect_green.Width>0)
                {
                    LinearGradientBrush lBrush_green = new LinearGradientBrush(rect_green, Color.FromArgb(255, 28, 192, 0), Color.FromArgb(255, 35, 246, 0), LinearGradientMode.Horizontal);
                    g.FillRectangle(lBrush_green, rect_green);
                }

                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Far;
                stringFormat.LineAlignment = StringAlignment.Center;
                stringFormat.Trimming = StringTrimming.EllipsisCharacter;

                StringFormat stringFormat2 = new StringFormat();
                stringFormat2.Alignment = StringAlignment.Near;
                stringFormat2.LineAlignment = StringAlignment.Center;
                stringFormat2.FormatFlags = StringFormatFlags.LineLimit;
                stringFormat2.Trimming = StringTrimming.EllipsisCharacter;

                //clock
                Font ClockFont = new Font("Verdana", 0.1875f * (float)height, FontStyle.Bold);
                Rectangle clock = new Rectangle(0, 1, width - (int)(width * 0.03f), (int)(height / 2.0f)+1 );
                e.Graphics.DrawString(time, ClockFont, Brushes.White, clock, stringFormat);

                //how long
                Rectangle hlong = new Rectangle(0, (int)(height / 2.0f)+1 , width - ((int)(width * 0.03)), (int)((height) / 2.0f) );
                e.Graphics.DrawString(diff, ClockFont, Brushes.White, hlong, stringFormat);

                // first
                Rectangle FirstItem = new Rectangle((int)(width * 0.03), 1, (int)(width * 0.75f), (int)((height) / 2.0f)+1 );
                e.Graphics.DrawString(itema, ClockFont, Brushes.White, FirstItem, stringFormat2);

                // second
                    Rectangle SecondItem = new Rectangle((int)(width * 0.03), (int)((height / 2.0f))+1 , (int)(width * 0.75f), (int)((height) / 2.0f) );
                e.Graphics.DrawString(itemb, ClockFont, Brushes.White, SecondItem, stringFormat2);
            }
        }

        private void clockupdate_Tick(object sender, EventArgs e)
        {
            time = DateTime.Now.ToString("HH:mm");
        }

        private void HideFsOsd_Tick(object sender, EventArgs e)
        {
            hideWindow();
            fsodshown = false;
        }

        public void restarthideOSD()
        {
            HideFsOsd.Stop();
            HideFsOsd.Start();
        }

        public void showWindow()
        {
            if (Properties.Settings.Default.FullScreen && Properties.Settings.Default.EpgFs)
            {
                this.StartPosition = FormStartPosition.Manual;
                
                //lets calculate position 
                
                float width = ((float)Properties.Settings.Default.EpgPopUpWidthPercent/100.0f )* parent.Width; // width allways fixed relative to the screen width
                if (width > parent.Width)
                    width = parent.Width;

                float left=1;

                if (Properties.Settings.Default.EpgPopUpAlign == "right")
                {
                    left = (parent.Width - (int)Math.Round(width, 0)) + parent.Location.X - Properties.Settings.Default.EpgPopUpXOffset;
                    if (left <= 0)
                        left = 0;
                }
                else if (Properties.Settings.Default.EpgPopUpAlign == "center")
                {
                    left = left = ((float)parent.Width - width)/2.0f + parent.Location.X ;
                    if (left <= 0)
                        left = 0;
                }
                else if (Properties.Settings.Default.EpgPopUpAlign == "left")
                {
                    left = Properties.Settings.Default.EpgPopUpXOffset + parent.Location.X;
                    if (left + width <= this.Width)
                        left = 0;
               }

                SetWindowPos(this.Handle.ToInt32(), HWND_TOPMOST,
                (int)left, parent.Height - Properties.Settings.Default.EPGPopUpHeight - Properties.Settings.Default.EPGpopupYOffset + parent.Location.Y, (int)width, Properties.Settings.Default.EPGPopUpHeight,
                SWP_NOACTIVATE);

                ShowWindow(this.Handle, SW_SHOWNOACTIVATE);
                fsodshown = true;
            }
        }

        public void hideWindow()
        {
            ShowWindow(this.Handle, SW_HIDE);
            fsodshown = false;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        protected override void WndProc(ref Message m)
        {
            //remote controll
            if (m.Msg == 0x8888 && Properties.Settings.Default.RemoteMode2)
            {
                //repost to parent
                PostMessage(parent.Handle, m.Msg, (int)m.WParam, (int)m.LParam);
                m.Result = new IntPtr(0);
            }
            else
            {
                base.WndProc(ref m);
            }
        }
    }
}
